﻿/*
 * @author: wizardc
 */

using System;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;

namespace Dou.UI
{
    /// <summary>
    /// 基于 TextMeshPro 实现的文本
    /// </summary>
    [ExecuteInEditMode]
    public class DTextMeshProUGUI : TextMeshProUGUI, IPointerClickHandler
    {
        [Serializable]
        public class LinkEvent : UnityEvent<string> {}
        
        [SerializeField]
        private bool _useGray = false;
        [SerializeField]
        private FontSetting _fontSetting;
        [SerializeField]
        private TextMeshProParam _param = new TextMeshProParam();
        [SerializeField]
        private LinkEvent _onLink = new LinkEvent();

        private bool _paramChanged = false;

        public bool useGray
        {
            set
            {
                if (_useGray != value)
                {
                    _useGray = value;
                    _paramChanged = true;
                }
            }
            get => _useGray;
        }

        public FontSetting fontSetting
        {
            set
            {
                if (_fontSetting != value)
                {
                    _fontSetting = value;
                    _paramChanged = true;
                }
            }
            get => _fontSetting;
        }

        public Color faceColor
        {
            set
            {
                if (_param.faceColor != value)
                {
                    _param.faceColor = value;
                    _paramChanged = true;
                }
            }
            get => _param.faceColor;
        }

        public float faceSoftness
        {
            set
            {
                if (_param.faceSoftness != value)
                {
                    _param.faceSoftness = value;
                    _paramChanged = true;
                }
            }
            get => _param.faceSoftness;
        }

        public float faceDilate
        {
            set
            {
                if (_param.faceDilate != value)
                {
                    _param.faceDilate = value;
                    _paramChanged = true;
                }
            }
            get => _param.faceDilate;
        }

        public bool useOutLine
        {
            set
            {
                if (_param.useOutLine != value)
                {
                    _param.useOutLine = value;
                    _paramChanged = true;
                }
            }
            get => _param.useOutLine;
        }

        public Color outLineColor
        {
            set
            {
                if (_param.outLineColor != value)
                {
                    _param.outLineColor = value;
                    _paramChanged = true;
                }
            }
            get => _param.outLineColor;
        }

        public float outLineWidth
        {
            set
            {
                if (_param.outLineWidth != value)
                {
                    _param.outLineWidth = value;
                    _paramChanged = true;
                }
            }
            get => _param.outLineWidth;
        }
        
        /// <summary>
        /// 点击超链接的回调
        /// </summary>
        public LinkEvent onLink
        {
            set => _onLink = value;
            get => _onLink;
        }

        protected override void Awake()
        {
            base.Awake();
            _paramChanged = true;
        }

        public void SetColor(float r, float g, float b, float a = 1)
        {
            color = new Color(r, g, b, a);
        }

        public void SetColor32(int r, int g, int b, int a = 255)
        {
            color = new Color(r / 255.0f, g / 255.0f, b / 255.0f, a / 255.0f);
        }

        private void SetFontMaterial()
        {
            if (_fontSetting == null)
            {
                return;
            }
            var fs = useGray ? _fontSetting.grayFont : _fontSetting;
            font = fs.font;
            spriteAsset = fs.sprite;
            fontMaterial = TMPFontMatMgr.instance.GetMaterial(fs, _param);
        }

        private void LateUpdate()
        {
            if (_paramChanged)
            {
                _paramChanged = false;
                SetFontMaterial();
            }
        }

        public void OnPointerClick(PointerEventData eventData)
        {
            if (Vector2.Distance(eventData.position, eventData.pressPosition) >= 30)
            {
                return;
            }
            var linkIndex = TMP_TextUtilities.FindIntersectingLink(this, eventData.pressPosition, eventData.pressEventCamera);
            if (linkIndex == -1)
            {
                return;
            }
            TMP_LinkInfo linkInfo = textInfo.linkInfo[linkIndex];
            _onLink?.Invoke(linkInfo.GetLinkID());
        }
    }
}
